iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0

昨天介紹了內部類的作用,及局部內部類今天的主角就是....

一般內部類

把一個類別放在另一個類別內,屬於類別成員,因為屬於其外部類別的成員,所以可以用private、protected 、static修飾

public class OuterClass{
  //此處可以定義內部類別
}
public class Test01 {
	public static void main(String[] args) {
		//建立物件:先有外再有內
		Outer01.Inner01 i01 = new Outer01().new Inner01();
		i01.show();
		Outer01 o01 = new Outer01();
		o01.get();
		
		Outer01.AA aa = Outer01.AA.左;
	}
}
//------------------
class Outer01{
	int a = 200;
	void get() {
		int c2 = 1;
		System.out.println("方法內區域變數:"+c2);
		System.out.println("本類的成員變數:"+this.a);
		System.out.println("內部類成員變數:"+new Inner01().b);
	}
	class Inner01{//一般內部類
		int b = 99;
		void show() {
			int b2 = 99999;
			System.out.println("方法內區域變數:"+b2);
			System.out.println("本類的成員變數:"+this.b);
			System.out.println("外部類成員變數:"+Outer01.this.a);
		}
	}
	enum AA{
		左,右;
	}
	abstract class BB{}
	interface CC{}
	class DD extends BB implements CC{}
}

編譯上面的程式,可以發現一般內部類的class檔命名會以這種形式:

OuterClass$InnerClass.class

為什麼一般內部類可以直接存取其外部類別的private 實例變數?

因為一般內部類別物件裡存放了一個寄生的外部類別物件參照

記憶體配置:

https://ithelp.ithome.com.tw/upload/images/20231011/201631395C3fCJw0YL.png

存取變數的順序:

方法內->內部類別->外部類别

當在非靜態內部類別的方法内存取某個變數時,系統優先在該方法內尋找是否存在該名字的局部變數,如果存在就使用該變數;如果不存在,則到該方法所在的內部類別中尋找是否存在該名字的成員變數,如果存在則使用該成員變數;如果不存在,則到該内部類別所在的外部類别中尋找是否存在該名字的成員變數,如果存在則使用該成員變數;如果依然不存在,系統將出現編譯錯誤:提示找不到該變數

如果外部類別成員變數、內部類別成員變數與內部類別裡方法的局部變數同名,則可通過使用this.變數名外部類別的類别名稱.this.變數名 作為限定來區分

如:this.b、Outer01.this.a

外部類別要存取內部類變數要先建立內部類物件

如:new Inner01().b

非靜態內部類與外部類的關係:

一般內部類別物件必須寄生在外部類別物件裡,而外部類别物件則不必一定有內部類別物件寄生其中。如果存在一個非靜態內部類別物件,則一定存在一個被它寄生的外部類別物件。但外部類別物件存在時,外部類別物件裡不一定寄生了非靜態內部類別物件。因此外部類別物件存取非靜態內部類別成員時,可能非靜態普通內部類別物件根本不存在!而非靜態內部類別物件存取外部類別成員時,外部類别物件一定存在。

根據靜態成員不能存取非靜態成員的規則,外部類别的靜態方法、靜態程式碼區塊不能存取非靜態內部類別,包括不能使用非靜態內部類別定義變數、建立實例等。

總之,不允許在外部類別的靜態成員中直接使用非靜態內部類别

也不允許在一般內部類定義靜態成員,如:靜態方法、靜態成員變數、靜態初始化區塊

注意:

存取權限為private時,只有本類別可以讀取。

內部類也擁有建構子。

今天就到這邊嚕!!!


上一篇
Day 25 內部類 I
下一篇
Day 27 內部類 III
系列文
玩轉Java:從基礎打造你的程式超能力30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言